package com.bjsxt.service;

import com.bjsxt.constant.Constants;
import com.bjsxt.domain.Line;
import com.bjsxt.dto.CreateKLineDto;
import com.bjsxt.util.KlineTimeUtil;
import jdk.nashorn.internal.runtime.ListAdapter;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.math.BigDecimal;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

public class TradeKlineService implements CommandLineRunner {


    public static BlockingQueue<CreateKLineDto> queue = new LinkedBlockingDeque<>();

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public void run(String... args) throws Exception {
        while (true){
            CreateKLineDto poll = queue.poll(); // 获取数据 没有数据阻塞
            if (poll != null){
                for (com.bjsxt.enums.KlineType klineType : com.bjsxt.enums.KlineType.values()  ){
                    this.generateKline(poll,klineType);
                }
        }
    }
}

    private void generateKline(CreateKLineDto kLineData, com.bjsxt.enums.KlineType klineType) {
        //1.获取之前该K线的数据
        String redisKey = new StringBuilder("TRADE_KLINE:")
                .append(kLineData.getSymbol()).append(":")
                .append(klineType.getValue().toLowerCase()).toString();

        Long size = redisTemplate.opsForList().size(redisKey);
        DateTime dateTime = KlineTimeUtil.getKLineTime(klineType);
        //无数据放数据
        if (size == 0){
            Line line = new Line(dateTime,kLineData.getPrice(),kLineData.getVolume());

            redisTemplate.opsForList().leftPush(redisKey,line.toKline());
            return;
        }
        if (size>1000){
            redisTemplate.opsForList().rightPop(redisKey);
        }

        //有数据
        String mistoryKlineData = redisTemplate.opsForList().range(redisKey,0,1).get(0);
        Line line = new Line(mistoryKlineData);

        //如果当前时间还在上一个时间区间内
        if (dateTime.compareTo(line.getTime()) == 1){
            Line line1 = new Line();
            line.setTime(dateTime);
            //如果我们
            if (kLineData.getVolume().compareTo(BigDecimal.ZERO)==0){
                line1.setClose(line.getClose());
                line1.setLow(line.getLow());
                line1.setOpen(line.getOpen());
                line1.setHigh(line.getHigh());
                redisTemplate.opsForList().leftPush(redisKey,line.toKline());
            return;
            }

            line.setOpen(kLineData.getPrice());
            line.setClose(kLineData.getPrice());

            if (kLineData.getPrice().compareTo(line.getHigh())==0){
                line.setHigh(kLineData.getPrice());
                line.setLow(line.getClose());
            }

            if (kLineData.getPrice().compareTo(line.getLow()) == 1){
                line.setLow(kLineData.getPrice());
                line.setHigh(line.getClose());

            }

            line.setClose(kLineData.getPrice());
            redisTemplate.opsForList().set(redisKey,0,line.toKline());

            redisTemplate.opsForList().leftPush(redisKey,line.toKline());




        }

        if (kLineData.getVolume().compareTo(BigDecimal.ZERO) ==0){
            return;
        }
        line.setClose(kLineData.getPrice());
        if ( kLineData.getPrice().compareTo( line.getHigh() ) == 1){
            line.setHigh(kLineData.getPrice());
        }
        if ( kLineData.getPrice().compareTo( line.getLow() ) == 1){
            line.setLow(kLineData.getPrice());
        }

        line.setVolume(line.getVolume().add(kLineData.getVolume()));
        redisTemplate.opsForList().set(redisKey,0,line.toKline());




    }
    }
